/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package icontrole.core;

import java.util.Observable;
import java.util.Observer;
import javax.swing.Timer;

/**
 *
 * @author heliojr
 */
public class Centro implements Observer {

    private ServerQuanser _server;
    private Controlador _controlador;
    private int _tankout;
    private Timer _timer;
    private boolean searching = true;
    private boolean _expone = false;
    private boolean falgTr = true;
    private boolean falgTs = true;

    public boolean isFalgTs() {
        return falgTs;
    }

    public void setFalgTs(boolean falgTs) {
        this.falgTs = falgTs;
    }

    public boolean isFalgTr() {
        return falgTr;
    }

    public void setFalgTr(boolean falgTr) {
        this.falgTr = falgTr;
    }

    public boolean isSearching() {
        return searching;
    }

    public void setSearching(boolean searching) {
        this.searching = searching;
    }
    private int count = 0;

    public Centro(ServerQuanser server) {
        this._server = server;
        this._controlador = new Controlador();
        this._server.addObserver(this);

    }

    public Timer getTimer() {
        return _timer;
    }

    public void setTimer(Timer _timer) {
        this._timer = _timer;
    }
//TODO construir na interface para o controlador 6

    public void Execute() {
        if (!_expone) {
            if (this._server.isOperation()) {

                if (this._controlador.getTipoControlador() == 6) {
                    this.ExecutarFiveSystem();
                }
                if (this._controlador.getTipoControlador() == 5) {
                    ExecutarEESR();

                } else {
                    this._controlador.pegaSaida(_server.ler(_tankout));
                    this._server.escrever(this._controlador.blocoDeControle(), 0);
                    double ler_tk1 = this._server.ler(0);
                    this._server.setNivel_tk1(ler_tk1);
                    double ler_tk2 = this._server.ler(1);
                    this._server.setNivel_tk2(ler_tk2);
                    this._server.setSinalControle(_controlador.blocoDeControle());
                    this._server.setSinalErro(this._controlador.getErroAtual());
                }
            } else {
                this._controlador.pegaSaida(_server.ler(_tankout));
                //this._server.escrever(this._controlador.blocoDeControle(), 0);
                double ler_tk1 = this._server.ler(0);
                this._server.setNivel_tk1(ler_tk1);
                double ler_tk2 = this._server.ler(1);
                this._server.setNivel_tk2(ler_tk2);
                this._server.setSinalControle(_controlador.blocoDeControle());
                this._server.setSinalErro(this._controlador.getErroAtual());
            }

        } else {
            double ler_tk1 = this._server.ler(0);
            this._server.setNivel_tk1(ler_tk1);
            double ler_tk2 = this._server.ler(1);
            this._server.setNivel_tk2(ler_tk2);
        }
    }

    private void ExecutarEESR() {
        this._controlador.pegaSaida(_server.ler(_tankout));
        double eesf = this._controlador.controleEESR();
        //this._server.escrever(this._controlador.controleEESF()[1], 1);
        double ler_tk1 = this._server.ler(0);
        this._server.setNivel_tk1(ler_tk1);
        double ler_tk2 = this._server.ler(1);
        this._server.setNivel_tk2(ler_tk2);
        eesf = eesf - (_controlador.getConst_k0() * ler_tk1 + _controlador.getConst_k1() * ler_tk2);
        this._server.escrever(eesf, 0);
        this._server.setSinalControle(eesf);
        this._server.setSinalErro(this._controlador.getErroAtual());
    }

    public void repassarParametros(double nivelDesejado, int tipoControlador, double kP, double varI, double varD, int tankout, int tipoI, int tipoD, boolean expone) {

        this._controlador.setValorDesejado(nivelDesejado);
        this._controlador.setTipoControlador(tipoControlador);
        this._controlador.setKp(kP);
        this._controlador.setKd(devolveConstanteKd(tipoD, varD));
        this._controlador.setKi(devolveConstanteKi(tipoI, varI));
        this.setTankout(tankout);
        this._expone = expone;
    }

    public double devolveConstanteKi(int tipoI, double varI) {
        int tipoControlador = tipoI;
        double Kp = getControlador().getKp();
        double variavelI = varI;

        //O valor entrado e o tempo de integracao
        if (tipoControlador == 0) {
            return Kp / variavelI;
        } else {//O valor entrado e a constante de integracao
            return variavelI;
        }
    }

    public double devolveConstanteKd(int tipoD, double varD) {
        int tipoControlador = tipoD;
        double Kp = getControlador().getKp();
        double variavelD = varD;

        //O valor entrado e o tempo de integracao
        if (tipoControlador == 0) {
            return Kp * variavelD;
        } else {//O valor entrado e a constante de integracao
            return variavelD;
        }
    }

    /**
     * @return the _client
     */
    public ServerQuanser getServer() {
        return _server;
    }

    /**
     * @param client the _client to set
     */
    public void setServer(ServerQuanser server) {
        this._server = server;
    }

    /**
     * @return the _controlador
     */
    public Controlador getControlador() {
        return _controlador;
    }

    /**
     * @param controlador the _controlador to set
     */
    public void setControlador(Controlador controlador) {
        this._controlador = controlador;
    }

    public int getTankout() {
        return _tankout;
    }

    public void setTankout(int _tankout) {
        this._tankout = _tankout;
    }

    public void update(Observable o, Object arg) {

        this.Execute();
    }

    public void setExpOne(boolean b) {
        this._expone = b;
    }

    public void ExpOne(Double tensao, double nivel_, boolean b) {
        this._server.escrever(tensao, 0);
        this._expone = b;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public void repassarParametros(double nivel_, int controlador_, int tank_, double cst_k0_, double cst_k1_, double cst_ki_, boolean expone) {
        this._controlador.setValorDesejado(nivel_);
        this._controlador.setTipoControlador(controlador_);
        this._controlador.setConst_k0(cst_k0_);
        this._controlador.setConst_k1(cst_k1_);
        this._controlador.setConst_ki(cst_ki_);
        this.setTankout(tank_);
        this._expone = expone;
    }

    private void ExecutarFiveSystem() {
        this._controlador.pegaSaida(_server.ler(_tankout));
        double eesf = this._controlador.controleEESR();
        //this._server.escrever(this._controlador.controleEESF()[1], 1);
        this._controlador.FiveSystem(eesf);

        double ler_tk1 = this._controlador.getMatrix_X()[0];//this._server.ler(0);
        this._server.setNivel_tk1(ler_tk1);
        double ler_tk2 = this._controlador.getMatrix_X()[1];//this._server.ler(1);
        this._server.setNivel_tk2(ler_tk2);
        eesf = eesf - (_controlador.getConst_k0() * ler_tk1 + _controlador.getConst_k1() * ler_tk2);
        this._server.escrever(eesf, 0);
        this._server.setSinalControle(eesf);
        this._server.setSinalErro(this._controlador.getErroAtual());
    }

    public void repassarParametros(double nivel_, int controlador_, int tank_, double cst_k0_, double cst_k1_, double cst_ki_, double[] Ad, double[] Bd, double[] Ml, boolean b) {
        repassarParametros(nivel_, controlador_, tank_, cst_k0_, cst_k1_, cst_ki_, _expone);
        double[] mI = {1, 0, 0, 1};
        double[] mC = {0, 1};
        this.getControlador().setMatrix_A(Ad);
        this.getControlador().setMatrix_B(Bd);
        this.getControlador().setMatrix_L(Ml);
        this.getControlador().setMatrix_I(mI);
        this.getControlador().setMatrix_C(mC);
    }
}
